namespace SimpleWebServices.Models
{
    using System;
    using System.Collections.Generic;
    using System.Collections.ObjectModel;
    using System.Xml;
    using System.Xml.Schema;
    using System.Xml.Serialization;
    using SimpleWebServices.Data;
    using SimpleWebServices.Xml;

    [XmlRoot("urlset", Namespace = "http://www.sitemaps.org/schemas/sitemap/0.9")]
    public sealed class SiteMapUrlSet : Record, IXmlSerializable, IXmlSerializerNamespaces
    {
        private XmlSerializerNamespaces _declarations;

        public SiteMapUrlSet()
        {
            this.Objects = new Collection<object>();

            this._declarations = new XmlSerializerNamespaces();
            this._declarations.Add(string.Empty, "http://www.sitemaps.org/schemas/sitemap/0.9");
        }

        public override string Entity
        {
            get
            {
                Entity value = new Entity();
                value.Append(this.Objects);

                return value;
            }
        }

        public Collection<object> Objects
        {
            get;
            private set;
        }

        [XmlNamespaceDeclarations]
        public XmlSerializerNamespaces XmlNamespaceDeclarations
        {
            get
            {
                return this._declarations;
            }

            set
            {
                this._declarations = value;
            }
        }

        XmlSchema IXmlSerializable.GetSchema()
        {
            throw new NotSupportedException();
        }

        void IXmlSerializable.ReadXml(XmlReader reader)
        {
            if (null == reader)
            {
                throw new ArgumentNullException("reader");
            }

            if (reader.IsEmptyElement)
            {
                reader.Read();
            }
            else
            {
                string name = reader.Name;
                while (true)
                {
                    if (XmlNodeType.EndElement == reader.NodeType && reader.Name == name)
                    {
                        reader.Read();
                        break;
                    }
                    else if ("url".Equals(reader.Name, StringComparison.OrdinalIgnoreCase))
                    {
                        this.Objects.Add(reader.ReadOuterXml().Deserialize<SiteMapUrl>());
                    }
                    else if ("fold:publisher".Equals(reader.Name, StringComparison.OrdinalIgnoreCase))
                    {
                        this.Objects.Add(reader.ReadOuterXml().Replace("fold:", string.Empty).Deserialize<SiteMapPublisher>());
                    }
                    else if ("publisher".Equals(reader.Name, StringComparison.OrdinalIgnoreCase))
                    {
                        IEnumerable<SiteMapUrl> items = reader.ReadOuterXml().Deserialize<SiteMapPublisher>().Publish();
                        if (null != items)
                        {
                            foreach (SiteMapUrl item in items)
                            {
                                this.Objects.Add(item);
                            }
                        }
                    }
                    else
                    {
                        reader.Read();
                    }
                }
            }
        }

        void IXmlSerializable.WriteXml(XmlWriter writer)
        {
            if (null == writer)
            {
                throw new ArgumentNullException("writer");
            }

            foreach (object item in this.Objects)
            {
                writer.WriteRaw(item.Serialize().CreateNavigator().OuterXml.Replace(" xmlns=\"http://www.sitemaps.org/schemas/sitemap/0.9\"", string.Empty));
            }
        }
    }
}